#include<errno.h>
#include<sys/uio.h>
#include<unistd.h>

#include "Buffer.h"

// 从fd读入数据 LT模式
//Buffer缓冲区有大小，但是fd中数据是流式的，不知道tcp数据大小
ssize_t Buffer::readFd(int fd, int *saveErrno)
{
    char extrabuf[65536] = {0};//栈上的内存空间
    struct iovec vec[2]; //先向vec[0]填写数据，vec[0]写满后，向vec[1]写

    const size_t writeable = writeableBytes(); //可写大小
    vec[0].iov_base = begin() + writerIndex_;
    vec[0].iov_len = writeable;

    vec[1].iov_base = extrabuf;
    vec[1].iov_len = sizeof extrabuf;

    const int iovcnt = (writeable <sizeof extrabuf) ? 2 : 1;
    const ssize_t n = ::readv(fd, vec, iovcnt);
    if(n < 0)
    {
        *saveErrno = errno;
    }
    else if(n <= writeable)
    {
        writerIndex_ += n;
    }
    else//extrabuf也写入数据了
    {
        writerIndex_ = buffer_.size();
        append(extrabuf, n - writeable);
    }
    return n;
}

ssize_t Buffer::writeFd(int fd, int* saveErrno)
{
    ssize_t n = ::write(fd, peek(), readableBytes());
    if(n < 0)
    {
        *saveErrno = errno;
    }
    return n;
}